﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////


#pragma once

#include "GcmpApplicationInterface.h"

namespace gcmp
{
    class ISplashScreen;
    class IApplicationWindow;
    class IAddinManager;
    class IApplicationEvent;
    class IApplicationConfig;
    class IProductBasicInformation;
    class IApplicationCloseStrategy;
    class IExternalEvent;
  
    /// \brief  主程序
    class GCMP_APPLICATION_INTERFACE_EXPORT IApplication
    {
    public:
        /// \brief 获取已经创建的主程序接口
        ///
        /// \return 如果没有创建过Application则返回空指针
        /// \see IApplication* ApplicationManager::Create(int& argc, char** argv)
        static IApplication* Get();

        /// \brief 析构函数
        virtual ~IApplication() = 0;

        /// \brief 注册产品基本信息
        ///
        /// \param opIProductBasicInformation 产品基本信息指针
        /// \see IProductBasicInformation
        virtual void SetProductBasicInformation(OwnerPtr<IProductBasicInformation> opIProductBasicInformation) = 0;

        /// \brief 获取产品基本信息
        ///
        /// \return 产品基本信息指针，如果没有注册过则返回空指针
        /// \see IProductBasicInformation
        virtual const IProductBasicInformation* GetProductBasicInformation() const = 0;

        /// \brief 获取命令行参数
        ///
        /// 获取命令行参数，第一个是程序名
        /// \return 所有命令行参数
        virtual std::vector<std::wstring> GetCommandLineArgs() const = 0;

        /// \brief 获取程序配置 去掉
        ///
        /// \return IApplicationConfig指针
        /// \see IApplicationConfig
        virtual IApplicationConfig* GetConfig() const = 0;

        /// \brief 进入主事件循环
        ///
        /// 调用后进入主事件循环，程序接收来自操作系统窗口系统的事件，并分发到程序的各个窗体
        /// \return 0表示正常退出，其他代表有异常
        virtual int Execute() = 0;

        /// \brief 获取启动画面
        ///
        /// \return 启动画面指针
        /// \see ISplashScreen
        virtual ISplashScreen* GetSplashScreen() const = 0;

        /// \brief 获取主窗口
        ///
        /// \return 主窗口指针
        /// \see IApplicationWindow
        virtual IApplicationWindow* GetApplicationWindow() const = 0;

        /// \brief 获取插件管理器
        ///
        /// \return 插件管理器指针
        /// \see IAddinManager
        virtual IAddinManager* GetAddinManager() = 0;

        /// \brief 获取主程序事件
        ///
        /// \return 主程序事件指针
        /// \see IApplicationEvent
        virtual IApplicationEvent* GetApplicationEvent() = 0;

        /// \brief 设置程序关闭策略
        ///
        /// 平台有自己的程序关闭逻辑，外部开发者也可以定制并替换。
        /// \param opCloseStrategy 关闭策略。
        /// \return 是否设置成功
        /// \see IApplicationCloseStrategy
        virtual bool SetCloseStrategy(OwnerPtr<IApplicationCloseStrategy> opCloseStrategy) = 0;

        /// \brief 获取程序关闭策略
        ///
        /// 外部开发者没有定制程序关闭策略时，返回nullptr，平台执行自己的关闭逻辑：
        ///     对所有被修改过的文件依次询问是否需要保存。
        /// \return IApplicationCloseStrategy 定制的程序关闭策略
        virtual IApplicationCloseStrategy * GetCloseStrategy() = 0;

        /// \brief 主窗口关闭前，通知主程序
        ///
        /// \param isClosedByUser 主窗口是否被用户手动关闭
        virtual void PreClose(bool isClosedByUser) = 0;

        /// \brief 同步发送事件
        /// \param pEvent 要发送的事件
        virtual bool SendEvent(OwnerPtr<IExternalEvent> pEvent) = 0;

        /// \brief 异步发送事件
        /// \param pEvent 要发送的事件
        virtual void PostEvent(OwnerPtr<IExternalEvent> pEvent) = 0;

        /// \brief 初始化
        virtual void Initialize() = 0;
    };

}   // end namespace gcmp
